import { singleIns } from "./optimize";
class FadeIn {
  /**
   * @description: 生成fade in动画，给元素添加类名即可，无需其他任何改动(注意：基于的是合成线程的transform translate，不要在已经使用translate的元素上添加)
   * @param {*} className 观察的类名，默认是fadeIn
   * @param {*} fadeDistance 渐入距离
   * @param {*} time  渐入动画时间
   * @return {*}
   */
  constructor({ fadeDistance = 80, time = 400, className = 'fadeIn', firstMove = true }) {
    this.observer = {};
    this.className = className;
    this.fadeDistance = fadeDistance;
    this.time = time;
    this.isObserving = false;
    this.elements = []; // 用于缓存查询到的元素
    // 初始就在视野中时，是否展示动画
    this.firstMove = firstMove
    this.firstInSight = true //页面刷新的时候（初始状态），观察的元素是否在视野中
  }

  launch(once = false) {
    if (typeof IntersectionObserver === 'undefined') {
      console.error('Current browsers do not support IntersectionObserver');
      return;
    }
    if (this.isObserving) return
    this.isObserving = true;
    this.observer = new IntersectionObserver(entries => {
      entries.forEach(entry => {
        const rect = entry.target.getBoundingClientRect();
        const viewportHeight = window.innerHeight;
        const elementHeight = rect.height;
        if (entry.isIntersecting) {
          if (rect.bottom > elementHeight) {
            // HACK 底部进入或初始进入

            // 如果是页面刷新的时候就在视野中，立即展示动画
            if (this.firstInSight && this.firstMove) {
              entry.target.style.opacity = "0";
              entry.target.style.transform = `translateY(${this.fadeDistance}px)`;
              // 强制重绘
              window.getComputedStyle(entry.target).opacity;
            }
            entry.target.style.transition = `all ease-in-out ${this.time}ms`;
            entry.target.style.opacity = "1";
            entry.target.style.transform = 'translateY(0px)';
          } else {
            // HACK 顶部进入
            entry.target.style.transition = "all 0ms";
            entry.target.style.opacity = "1";
          }
          // 如果once为true，只观察一次
          once && this.exit();
        } else {
          if (rect.bottom < viewportHeight) {
            // HACK 滚轮下移离开
          } else {
            // HACK 滚轮上移离开或初始离开

            // 更新是否初始就在视野中
            this.firstInSight && (this.firstInSight = false)
            entry.target.style.opacity = "0";
            entry.target.style.transform = `translateY(${this.fadeDistance}px)`;
          }
        }
      });
    });
    if (this.elements.length === 0) {
      this.elements = Array.from(document.querySelectorAll(`.${this.className}`))
    }
    this.elements.forEach(element => {
      this.observer.observe(element);
    });
  }

  exit() {
    if (this.isObserving) {
      this.isObserving = false;
      this.elements.forEach(element => {
        this.observer.unobserve(element);
      });
      // release IntersectionObserver
      this.observer.disconnect();
    }
  }
}
// 默认导出单例模式
export default singleIns(FadeIn)

export { FadeIn }